﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Simulation
{
	public partial class F_MAIN: Form
	{
		C_COMM	CM = new C_COMM();
		C_NODE	ND = new C_NODE();
		F_SETT	ST = new F_SETT();
		F_BSKS	KS = new F_BSKS();
		F_NDLG	LG = new F_NDLG();

		C_RPBS	RP = new C_RPBS();
		C_SEFF	SF = new C_SEFF();
		C_LEAP	LP = new C_LEAP();
		C_FRIA	FR = new C_FRIA();
		C_SINK	SK = new C_SINK();
		C_EVNT	ET = new C_EVNT();

		C_MSSG	MG = new C_MSSG();

		C_NODE[]	SN;
		Button[]	BT;
		
		int		SMND = -1;
		int		x, y;

		public F_MAIN()
		{
			InitializeComponent();			
		}

		private void BT_MAKE_Click( object sender, EventArgs e )
		{
			BT_MAKE.Tag = "1";
			ClearNodes();

			SMND = ST.TTND;

			BT = new Button[SMND];
			SN = new C_NODE[SMND];

			// DesignFormSize();

			CreateField();
			CreateNodes();
			CopyNodeLocation();
			DistributeKeys();
			CreateCost();
			MakeRoutingPath();

			MakeHopCount();

			if ( CheckBTMake() )
				return;

			if ( CheckAttacks() )
				return;

			if ( ST.OATYP == 1 )
				MakeAttackedNodes();

			if ( ST.ODTYP == 1 )
				TagAttackedNodes();
		}

		public void MakeHopCount()
		{
			for ( int i = 1; i < ST.OTTND; i++ )
			{
				if ( SN[i].PRID == -1 )
					ChangeBTColor( C_COMM.NPRT, i );
				else
					SN[i].HPCT = RP.MakeHopCount( i, SN );
			}
		}

		public void DesignFormSize()
		{
			if ( ( PN_SNFD.Size.Width != ST.OWDTH ) && ( PN_SNFD.Size.Height != ST.OHGHT ) )
			{
				this.Width	= this.Size.Width	- ( 1000 - ST.OWDTH );
				this.Height	= this.Size.Height	- ( 1000 - ST.OHGHT );

				this.PN_SUBB.Left	= PN_SUBB.Left - ( 1000 - ST.OWDTH );
			}
		}

		public void ClearNodes()
		{
			PN_SNFD.Controls.Clear();
			PN_SNFD.Invalidate( true );
		}

		public void CreateField()
		{
			PN_SNFD.Width	= ST.OWDTH;
			PN_SNFD.Height	= ST.OHGHT;
		}

		public void CreateCost()
		{
			RP.MeasureCost( SN );
		}

		public void DistributeKeys() 
		{
			for( int i = 1; i < ST.OTTND; i ++ )
			{
				if ( ST.OSEFF == 1 )
				{
					SN[i].SPID = SF.SetPID();
					SN[i].KEYS = SF.SetKeys( SN[i].SPID );
					SN[i].SKEY = SF.SetStringKey( SN[i].KEYS );
				}

				if ( ST.OLEAP == 1 )
				{
					SN[i].INDK = LP.SetINDK();
					SN[i].PRWK = LP.SetPRWK();
					SN[i].CLSK = LP.SetCLSK();
					SN[i].GRPK = LP.SetGRPK();
				}

				if ( ST.OPPMT == C_COMM.TRUE )
				{
					SN[i].SPID = SF.SetPID();
					SN[i].KEYS = SF.SetKeys( SN[i].SPID );
					SN[i].SKEY = SF.SetStringKey( SN[i].KEYS );

					SN[i].INDK = LP.SetINDK();
					SN[i].PRWK = LP.SetPRWK();
					SN[i].CLSK = LP.SetCLSK();
					SN[i].GRPK = LP.SetGRPK();
				}
			}
		}

		public void MakeRoutingPath()
		{
			C_RPBS RB = new C_RPBS();
			RB.SetPanel( this.PN_SNFD );
			RB.DrawRoutingPath( SN );
		}

		public void CopyNodeLocation()
		{
			for ( int i = 0; i < SMND; i++ )
			{
				SN[i] = new C_NODE();
				SN[i].SetData( i, BT[i].Left, BT[i].Top );
			}
		}

		public void CreateNodes()
		{
			ND.SetSize( ST.OWDTH, ST.OHGHT );

			for ( int i = 0; i < SMND; i++ )
			{
				BT[i] = new Button();
				BT[i].Name = i.ToString();

				if ( i == 0 )
				{
					BT[i].Text = "B";
					BT[i].Font = new Font( "맑음고딕", 6.0F );

					BT[i].Width		= 20;
					BT[i].Height	= 20;

					BT[i].Left	= ST.OBSPX;
					BT[i].Top	= ST.OBSPY;
				}
				else
				{
					BT[i].Width = 10;
					BT[i].Height = 10;

					x = ND.RandPosX( i );
					y = ND.RandPosY( i );

					CheckDulication( i, x, y );

					BT[i].Left = x;
					BT[i].Top = y;
				}

				PN_SNFD.Controls.Add( BT[i] );

				BT[i].Click += new System.EventHandler( BT_NODE_Click );
			}
		}

		void CheckDulication( int last, int tmp_x, int tmp_y )
		{
			for ( int i = 0; i < last; i++ )
			{
			    while ( true )
			    {
			        if ( ( Math.Abs( tmp_x - BT[i].Left ) <= 40 ) && ( Math.Abs( tmp_y - BT[i].Top ) <= 40 ) )
			        {
			            tmp_x = ND.RandPosX( i );
			            tmp_y = ND.RandPosY( i );
			        }
			        else
			            break;
			    }
			}

			x = tmp_x;
			y = tmp_y;
		}
		
		void BT_NODE_Click( object sender, EventArgs e )
		{
			int id = int.Parse( ( ( Button )sender ).Name );

			F_NDIF NF = new F_NDIF( SN[id].NDID, SN[id].PRID, SN[id].HPCT, SN[id].ENGY, SN[id].MGCT, SN[id].COST, SN[id].CTFR, SN[id].CTFM, SN[id].CHLD );
			NF.StartPosition = FormStartPosition.Manual;
			NF.DesktopLocation = new Point( System.Windows.Forms.Cursor.Position.X, System.Windows.Forms.Cursor.Position.Y );
			NF.Owner = this;
			NF.Show();
		}

		private void BT_SETT_Click( object sender, EventArgs e )
		{
			ST.ShowDialog();
		}

		private void BG_NDLG_Click( object sender, EventArgs e )
		{
			try
			{
				// [ General Inoformation ]
				int[]		ndid = new int[ST.OTTND];
				int[]		prid = new int[ST.OTTND];
				int[]		hpct = new int[ST.OTTND];
				float[]		engy = new float[ST.OTTND];
				float[]		cost = new float[ST.OTTND];
				int[]		mgct = new int[ST.OTTND];
				int[]		chld = new int[ST.OTTND];

				// [ LOG ]
				int[]		ctfr = new int[ST.OTTND];
				int[]		ctfm = new int[ST.OTTND];
				int[]		rper = new int[ST.OTTND];
				int[]		dfrc = new int[ST.OTTND];
				int[]		dfmc = new int[ST.OTTND];

				// [ SEF ]
				int[]		spid = new int[ST.OTTND];
				string[]	skey = new string[ST.OTTND];

				// [ LEAP ]
				int[]		indk = new int[ST.OTTND];
				int[]		prwk = new int[ST.OTTND];
				int[]		clsk = new int[ST.OTTND];
				int[]		grpk = new int[ST.OTTND];

				for ( int i = 0; i < ST.OTTND; i++ )
				{
					// [ General Inoformation ]
					ndid[i] = SN[i].NDID;
					prid[i] = SN[i].PRID;
					hpct[i] = SN[i].HPCT;
					engy[i] = SN[i].ENGY;
					cost[i] = SN[i].COST;
					mgct[i] = SN[i].MGCT;
					chld[i] = SN[i].CHLD;

					// [ LOG ]
					ctfr[i] = SN[i].CTFR;
					ctfm[i] = SN[i].CTFM;
					rper[i] = SN[i].RPER;
					dfrc[i] = SN[i].DFRC;
					dfmc[i] = SN[i].DFMC;

					// [ SEF ]
					spid[i] = SN[i].SPID;
					skey[i] = SN[i].SKEY;

					// [ LEAP ]
					indk[i] = SN[i].INDK;
					prwk[i] = SN[i].PRWK;
					clsk[i] = SN[i].CLSK;
					grpk[i] = SN[i].GRPK;
				}

				LG = new F_NDLG( SMND, ndid, prid, hpct, engy, cost, mgct, chld, ctfr, ctfm, rper, dfrc, dfmc, spid, skey, indk, prwk, clsk, grpk );
				LG.Show();
			}
			catch
			{
				MessageBox.Show( MG.MAIN_OPEN_NDLG );
				return;
			}
		}

		private void BT_PLAY_Click( object sender, EventArgs e )
		{
			

			MakeEvents();

			MessageBox.Show( MG.MAIN_SUCC );
		}

		private bool CheckAttacks()
		{
			int cmct = 0;

			for ( int i = 1; i < ST.OTTND; i++ )
			{
				if ( SN[i].CMND == true )
				{
					cmct++;

					if ( cmct == 5 )
						return true;
				}

				if ( SN[i].SKND == true )
					return true;
			}

			return false;
		}

		private void MakeEvents()
		{
			ET.SetValues( ST.OAQOE );
			ET.TransmitReport( SN );
		}

		private void TagAttackedNodes()
		{
			for ( int i = 1; i < ST.OTTND; i++ )
			{
				if ( SN[i].CMND == true )
					ChangeBTColor( C_COMM.CNMD, i );

				if ( SN[i].SKND == true )
					ChangeBTColor( C_COMM.SKND, i );
			}
		}

		private void MakeAttackedNodes()
		{
			FR.MakeCompromisedNodes( SN );
			SK.MakeSinkholeNode( SN );
			SK.MakeSinkholeNode( SN );
		}

		private void ChangeBTColor(	int C, int I )
		{
			switch( C )
			{
				// Initial Button Color
				case C_COMM.INIT:
					for ( int i = 0; i < ST.OTTND; i++ )
					{
						if ( ( SN[i].SKND == false ) && ( SN[i].CMND == false ) )
						{
							BT[i].BackColor = SystemColors.Control;
							BT[i].FlatStyle = FlatStyle.Standard;
						}
					}
					break;
				// Search Button
				case C_COMM.SCND:
					BT[I].BackColor = Color.Blue;
					BT[I].FlatStyle = FlatStyle.Popup;
					break;
				// Compromised Node
				case C_COMM.CNMD:
					BT[I].BackColor = Color.Yellow;
					BT[I].FlatStyle = FlatStyle.Popup;
					break;
				// Sinkhole Node
				case C_COMM.SKND:
					BT[I].BackColor = Color.Red;
					BT[I].FlatStyle = FlatStyle.Popup;
					break;
				// No Parent Node
				case C_COMM.NPRT:
					BT[I].BackColor = Color.Orange;
					BT[I].FlatStyle = FlatStyle.Popup;
					break;
			}
		}

		private bool CheckBTMake()
		{
			if ( BT_MAKE.Tag.ToString() == "0" )
			{
				MessageBox.Show( MG.MAIN_BTTN_ERRR );
				return true;
			}

			return false;
		}

		private void BT_SRCH_Click( object sender, EventArgs e )
		{
			int id = -1;

			if ( CheckBTMake() )
			{
				return;
			}

			// Check Null
			if ( TB_SRCH.Text.Length == 0 )
			{
				MessageBox.Show( MG.MAIN_SRCH );
				return;
			}			

			id = int.Parse( TB_SRCH.Text );

			// Check Node ID Range
			if ( ( id <= 1 ) || ( id > ST.OTTND ) )
			{
				MessageBox.Show( MG.MAIN_SRCH_ERRR );
				return;
			}
			
			// Initial Button Color
			if ( CB_SRCH.Checked == false ) 
			{
				ChangeBTColor( C_COMM.INIT, -1 );
			}

			ChangeBTColor( C_COMM.SCND, id );
		}

		private void BT_SRCH_KeyPress( object sender, KeyPressEventArgs e )
		{
			if ( !char.IsNumber( e.KeyChar ) && e.KeyChar != 8 )
				e.Handled = true;
		}

		private void BT_GKP_Click( object sender, EventArgs e )
		{
			KS.ShowDialog();
		}

		private void TB_SRCH_KeyPress( object sender, KeyPressEventArgs e )
		{
			if ( !char.IsNumber( e.KeyChar ) && e.KeyChar != 8 )
				e.Handled = true;
		}

		private void BT_PATH_Click( object sender, EventArgs e )
		{
			F_PATH PT = new F_PATH();
			PT.Show();
		}
	}
}
